// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

#include "Import/BDFImport/BulkData/Element/CBUSHParser.h"

#include <algorithm>
#include <cstdint>
#include <iostream>

#include "Utility/Logging/SGLogger.h"

#include "DataStructure/Input/Element/CBUSHData.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Element/IElementService.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (CBUSH);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::DataStructure;
/*
// file://./../../Doc/MarkDown/BulkData/CBUSH/CBUSH.md>
*/
// 以下需要修改
enum CBUSHKEY : std::uint8_t
{
    CBUSHKEY_EID = 2,
    CBUSHKEY_PID = 3,    // Property identification number of a PBUSH entry. (Integer > 0; Default = EID)
    CBUSHKEY_GA  = 4,    // Grid point identification number of connection points. See Remark 6. (GA > 0,GB >= 0 or blank)
    CBUSHKEY_GB  = 5,
    CBUSHKEY_X1  = 6,    // Components of orientation vector , from GA, in the displacement coordinate system at GA. (Real)
    CBUSHKEY_X2  = 7,
    CBUSHKEY_X3  = 8,
    CBUSHKEY_CID = 9,    // Element coordinate system identification. A 0 value means the basic coordinate system
                         // will be used. If CID is blank, then the element coordinate system is determined from
                         // GO or Xi. See  Figure 9-22 and Remark  3. (Integer > 0 or blank)
    CBUSHKEY_S    = 12,  // Location of spring damper. See  Figure 9-21 . (Real; Default = 0.5)
    CBUSHKEY_OCID = 13,  // Coordinate system identification of spring-damper offset. See Remark 9. (Integer > -1;
                         // Default = -1, which means the offset point lies on the line between GA and GB
                         // according to  Figure 9-22
    CBUSHKEY_S1 =
        14,  // Components of spring-damper offset in the OCID coordinate system if OCID > 0. See Figure 9-23 and Remark  9. (Real)
    CBUSHKEY_S2 = 15,
    CBUSHKEY_S3 = 16,

};

SG::DataStructure::Common::Status BDF::BULKDATA::ParseCBUSH (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                                             std::vector<std::string>&                               dividedEntryInfo)
{
    SG::DataStructure::FEM::CBUSHData tempCBUSH;  // 创建临时的CBUSH数据对象
    tempCBUSH.m_oCId = -1;                        // 设置OCID的默认值为-1
    tempCBUSH.m_s    = 0.5;                       // 设置S的默认值为0.5

    // TODO(bug 001) m_dominId的正确填写
    tempCBUSH.m_domainId = 1;  // 临时将m_domainId设置为1，待修复

                               // 调用divideBulkEntry函数，对EntryInfo进行分割

    int curIDKey = 1;  // 当前词条的索引，初始值为1

    // 遍历分割后的词条信息
    for (auto curStrKey : dividedEntryInfo)
    {
        // 判断当前词条是否为空
        bool const isEmpty = is_all_space (curStrKey);
        if (isEmpty)
        {
            curIDKey++;  // 如果为空，跳过，处理下一个词条
            continue;
        }

        // 判断当前词条是否为浮点数
        bool const isFloat = covertToScientificNotation (curStrKey);

        // 根据当前的词条索引，解析对应的数据
        switch (curIDKey)
        {
        case CBUSHKEY_EID:
            tempCBUSH.m_id  = convertToI64 (curStrKey);      // 解析EID并存储到tempCBUSH的m_id
            tempCBUSH.m_pId = tempCBUSH.m_id;                // 默认情况下，PID与EID相同
            break;
        case CBUSHKEY_PID:
            tempCBUSH.m_pId = convertToI64 (curStrKey);      // 如果提供了PID，则覆盖默认的PID
            break;
        case CBUSHKEY_GA:
            tempCBUSH.m_g[0] = convertToI64 (curStrKey);     // 解析GA并存储到tempCBUSH的m_g[0]
            break;
        case CBUSHKEY_GB:
            tempCBUSH.m_g[1] = convertToI64 (curStrKey);     // 解析GB并存储到tempCBUSH的m_g[1]
            break;
        case CBUSHKEY_X1:
            if (!isFloat)                                    // 如果X1不是浮点数，解析为网格点GO
            {
                tempCBUSH.m_go = convertToI64 (curStrKey);   // 解析GO并存储到tempCBUSH的m_go
            }
            else                                             // 否则，解析为X1分量
            {
                tempCBUSH.m_x1 = convertToReal (curStrKey);  // 解析X1并存储到tempCBUSH的m_x1
            }
            break;
        case CBUSHKEY_X2:
            tempCBUSH.m_x2 = convertToReal (curStrKey);      // 解析X2并存储到tempCBUSH的m_x2
            break;
        case CBUSHKEY_X3:
            tempCBUSH.m_x3 = convertToReal (curStrKey);      // 解析X3并存储到tempCBUSH的m_x3
            break;
        case CBUSHKEY_CID:
            tempCBUSH.m_coordId = convertToI64 (curStrKey);  // 解析坐标系ID并存储到tempCBUSH的m_coordId
            break;
        case CBUSHKEY_S:
            tempCBUSH.m_s = convertToReal (curStrKey);       // 如果提供了S，则覆盖默认值0.5
            break;
        case CBUSHKEY_OCID:
            tempCBUSH.m_oCId = convertToI64 (curStrKey);     // 解析OCID并存储到tempCBUSH的m_oCId
            break;
        case CBUSHKEY_S1:
            tempCBUSH.m_s1 = convertToReal (curStrKey);      // 解析S1并存储到tempCBUSH的m_s1
            break;
        case CBUSHKEY_S2:
            tempCBUSH.m_s2 = convertToReal (curStrKey);      // 解析S2并存储到tempCBUSH的m_s2
            break;
        case CBUSHKEY_S3:
            tempCBUSH.m_s3 = convertToReal (curStrKey);      // 解析S3并存储到tempCBUSH的m_s3
            break;
        default:
            break;
        }
        curIDKey++;  // 处理完当前词条后，索引加1
    }

    // 将解析后的CBUSH数据添加到数据库中
    return dbServiceFactory->get<IElementService> ()->Add (tempCBUSH);
}